package network

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/leeqiang250/go-common/util"
	"io"
	"io/ioutil"
	"net/http"
)

type HttpMethod string

const (
	HttpMethodGet  HttpMethod = "GET"
	HttpMethodPost HttpMethod = "POST"
)

type HttpReq struct {
	URL    string      `json:"url"`
	Method HttpMethod  `json:"method"`
	Param  interface{} `json:"param"`
}

type HttpRes interface {
}

func ExecuteJson(req *HttpReq, res HttpRes) error {
	var err error
	if nil == req {
		err = errors.New("http req is nil")
		util.Error.Println(err)
		return err
	}
	var _byte []byte
	var resp *http.Response
	if HttpMethodPost == req.Method {
		if nil == req.Param {
			resp, err = http.Post(req.URL, "application/json", nil)
		} else {
			_byte, err = json.Marshal(req.Param)
			if nil == err {
				resp, err = http.Post(req.URL, "application/json", ioutil.NopCloser(bytes.NewReader(_byte)))
			}
		}
	} else if HttpMethodGet == req.Method {
		resp, err = http.Get(req.URL)
	} else {
		err = fmt.Errorf("http url:%v not support method:%v", req.URL, req.Method)
	}
	if nil != err {
		util.Error.Println(err)
		return err
	}
	_byte, err = ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if nil != err {
		util.Error.Println(err)
		return err
	}
	if http.StatusOK != resp.StatusCode {
		err = fmt.Errorf("url:%v code:%v", req.URL, resp.StatusCode)
		util.Error.Println(err)
		return err
	}
	if 0 == len(_byte) || nil == res {
		return nil
	}
	err = json.Unmarshal(_byte, res)
	if nil != err {
		util.Error.Println(err)
		return err
	}
	return nil
}

func ExecuteRpc(req *HttpReq) ([]byte, error) {
	var err error
	if nil == req {
		err = errors.New("http req is nil")
		util.Error.Println(err)
		return nil, err
	}
	var _byte []byte
	var resp *http.Response
	if HttpMethodPost == req.Method {
		if nil == req.Param {
			resp, err = http.Post(req.URL, "application/json", nil)
		} else {
			resp, err = http.Post(req.URL, "application/json", req.Param.(io.Reader))
		}
	} else if HttpMethodGet == req.Method {
		resp, err = http.Get(req.URL)
	} else {
		err = fmt.Errorf("http url:%v not support method:%v", req.URL, req.Method)
	}
	if nil != err {
		util.Error.Println(err)
		return nil, err
	}
	_byte, err = ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if nil != err {
		util.Error.Println(err)
		return nil, err
	}
	//TODO
	//if http.StatusOK != resp.StatusCode {
	//	err = fmt.Errorf("url:%v code:%v", req.URL, resp.StatusCode)
	//	util.Error.Println(err)
	//	return nil, err
	//}
	//TODO
	return _byte, nil
}
